//
// Copyright 2001-2004 Stottler Henke Associates, Inc.
// All Rights Reserved.
////////////////////////////////////////////////////////////////////////////////

package com.stottlerhenke.simbionic.engine.parser;
import java.io.Serializable;

import com.stottlerhenke.simbionic.common.*;
import com.stottlerhenke.simbionic.engine.SB_SingletonBook;
import com.stottlerhenke.simbionic.engine.file.SB_StreamReader;
import com.stottlerhenke.simbionic.api.*;
import com.stottlerhenke.simbionic.api.SB_Param;

/**
 * Base class for variables of all types.
 * 
 * NOTE: to add new variable types, add it to the EVarType enum.  Create a new
 * subclass of WG_Variable (see WG_VarFloat for an example).  Modify the
 * static method ReadVariable() of this class.
 */
public abstract class SB_Variable implements Serializable  
{
  protected SB_Param _parameterValue;

  public SB_Variable() {
  }

  public SB_Variable Clone() throws SB_Exception
  {
        return null;
  }

  public SB_Param getSB_Param()
  {
    return _parameterValue;
  }
  
  abstract public void setSB_Param(SB_Param newParam) throws SB_Exception;
  

  public String toString(){
      return "";
  }

  public static SB_Variable readVariable(SB_StreamReader reader,SB_SingletonBook book,boolean initValue)
   throws SB_Exception
  {
    // read the variable type
    int type = reader.readInt();
    if ( 	(type < SB_VarType.kInvalid.getState()) || 
    			(type >= SB_VarType.kLAST_VARTYPE.getState() && type <= SB_VarType.kCLASS_START.getState() ) )
      throw new SB_FileException("Illegal variable type in file",
                                 EErrCode.kE_FORMAT);
    
    SB_Variable var = null;
    
    var = newVariable(type);
    if (initValue || type > SB_VarType.kCLASS_START.getState())
    {
    	var.load(reader,book);
    }

    return var;
  }

  protected abstract void load(SB_StreamReader reader,SB_SingletonBook book) 
		throws SB_Exception;

  public static SB_Variable newVariable(int type) throws SB_Exception
	{
    // create the appropriate variable subclass
    SB_Variable var = null;
    
    if(type == SB_VarType.kFloat.getState())
      var = new SB_VarFloat();
    else if(type == SB_VarType.kInteger.getState())
      var = new SB_VarInteger();
    else if(type == SB_VarType.kBoolean.getState())
      var = new SB_VarBoolean();
    else if(type == SB_VarType.kString.getState())
      var = new SB_VarString();
    else if(type == SB_VarType.kEntity.getState())
      var = new SB_VarEntity();
    else if(type == SB_VarType.kVector.getState())
      var = new SB_VarVector();
    else if(type == SB_VarType.kArray.getState())
      var = new SB_VarArray();
    else if(type == SB_VarType.kData.getState())
      var = new SB_VarData();
    else if(type == SB_VarType.kAny.getState())
      var = new SB_VarInvalid();
    else if(type == SB_VarType.kInvalid.getState())
      var = new SB_VarInvalid();
    else if(type > SB_VarType.kCLASS_START.getState())
    	var = new SB_VarClass(type);
    else  throw new SB_Exception("Unknown variable type " + type + ".", EErrCode.kE_FORMAT);

    return var;
  }

  public SB_VarType GetType() { return SB_VarType.kInvalid; }

  public static String TypeToString(SB_VarType type){
    if(type == SB_VarType.kFloat)
      return "float";
    else if(type == SB_VarType.kInteger)
      return "integer";
    else if(type == SB_VarType.kBoolean)
      return "boolean";
    else if(type == SB_VarType.kEntity)
      return "entity";
    else if(type == SB_VarType.kString)
      return "string";
    else if(type == SB_VarType.kData)
      return "data";
    else if(type == SB_VarType.kVector)
      return "vector";
    else if(type == SB_VarType.kAny)
      return "any";
    else if(type == SB_VarType.kArray)
      return "array";

    return "unknown";
  }

  public boolean bool() throws SB_Exception
	{
  	return false;
  }

  public SB_Variable opSUB(SB_Variable arg2) throws SB_Exception
	{
  	return null;
  }

  public SB_Variable opNOT() throws SB_Exception
	{
  	return null;
  }

  public SB_Variable opNEG() throws SB_Exception
	{
  	return null;
  }

  public SB_Variable opADD( SB_Variable arg2) throws SB_Exception
	{
  	return null;
  }

  public SB_Variable opMUL( SB_Variable arg2) throws SB_Exception
	{
  	return null;
  }

  public SB_Variable opDIV( SB_Variable arg2) throws SB_Exception
	{
  	return null;
  }

  public SB_Variable opEXP( SB_Variable arg2) throws SB_Exception
	{
  	return null;
  }

  public SB_Variable opMOD( SB_Variable arg2) throws SB_Exception
	{
  	return null;
  }

  public SB_Variable opLSS( SB_Variable arg2) throws SB_Exception  
	{
    return null;
  }

  public SB_Variable opGRT( SB_Variable arg2) throws SB_Exception  
	{
    return null;
  }

  public SB_Variable equals( SB_Variable arg2) throws SB_Exception  
	{
    return null;
  }

  public SB_Variable opNOTEq( SB_Variable arg2) throws SB_Exception  
	{
    return null;
  }

  public SB_Variable opLSSEq( SB_Variable arg2) throws SB_Exception  
	{
    return null;
  }

  public SB_Variable opGRTEq( SB_Variable arg2) throws SB_Exception  
	{
    return null;
  }

  public SB_Variable opAND( SB_Variable arg2) throws SB_Exception  
	{
    return null;
  }

  public SB_Variable opOr( SB_Variable arg2) throws SB_Exception  
	{
    return null;
  }

  public SB_Variable opAssign( SB_Variable var) throws SB_Exception 
	{
    return null;
  }

}